from tornado.web import authenticated
from common.BaseHandler import BaseHandler
from common.Models import Post, Category, Tag, PostCateMiddle, PostTagMiddle, PostUpdateHistory, Comment
from utils.DateHandler import DateHandler


def get_post_category(self, post_id):
    cate = self.session.query(Category) \
                .join(PostCateMiddle, PostCateMiddle.category_id == Category.id) \
                .filter(PostCateMiddle.post_id == post_id).first()
    return cate


def get_post_tags(self, post_id):
    tags = self.session.query(Tag) \
                .join(PostTagMiddle, PostTagMiddle.tag_id == Tag.id) \
                .filter(PostTagMiddle.post_id == post_id).all()
    return tags


class PostHandler(BaseHandler):
    @authenticated
    def get(self):
        if "api" in self.request.uri:
            result = self.result()
            try:
                data = self.get_params()
                page = int(data.get("page", 1))
                limit = int(data.get("limit", 10))
                posts = self.session.query(Post).filter_by(author_id=self.current_user, is_delete=0)
                post_count = posts.count()
                posts = posts.order_by(Post.create_time.desc()).limit(limit).offset((page - 1) * limit).all()
                data = []
                for post in posts:
                    cate = get_post_category(self, post.id)
                    tags = get_post_tags(self, post.id)
                    data.append({
                        "id": post.id,
                        "title": post.title,
                        "excerpt": post.excerpt,
                        "category": cate.name if cate else "",
                        "tags": [tag.name for tag in tags],
                        "views": post.views,
                        "comments": self.session.query(Comment).filter_by(post_id=post.id, is_delete=0).count(),
                        "modified_time": str(post.modified_time) if post.modified_time else "",
                        "create_time": str(post.create_time),
                    })
                result["status"] = 1
                result["msg"] = "查询成功！"
                result["data"] = {
                    "data_count": post_count,
                    "data_list": data
                }
            except Exception as e:
                self.logger.error(e)
                result = self.check_except_zh(e, msg="数据查询失败！")
            self.write(result)
        else:
            self.render("management/post.html")

    @authenticated
    def delete(self):
        if "api" in self.request.uri:
            result = self.result()
            try:
                data = self.get_body()
                post_id = self.data_null(data, "post_id", "请选择文章！")
                post = self.session.query(Post).filter_by(id=int(post_id), author_id=self.current_user, is_delete=0).first()
                if post:
                    post.is_delete = 1
                    self.session.commit()
                    result["status"] = 1
                    result["msg"] = "文章删除成功！"
            except Exception as e:
                self.session.rollback()
                self.logger.error(e)
                result = self.check_except_zh(e, msg="文章删除失败！")
            self.write(result)
        else:
            self.render("management/post.html")


class PostDetailHandler(BaseHandler):
    @authenticated
    def get(self, post_id):
        try:
            print(post_id)
            category_list = self.session.query(Category)\
                                .filter_by(author_id=self.current_user, is_delete=0)\
                                .order_by(Category.create_time.desc()).all()
            tag_list = self.session.query(Tag) \
                           .filter_by(author_id=self.current_user, is_delete=0) \
                           .order_by(Tag.create_time.desc()).all()
            post_obj = self.session.query(Post).filter_by(id=post_id, author_id=self.current_user, is_delete=0).first()
            if post_obj:
                cate = get_post_category(self, post_obj.id)
                tags = get_post_tags(self, post_obj.id)
                for i in tag_list:
                    i.is_checked = 0
                    for j in [tag.id for tag in tags]:
                        if i.id == j:
                            i.is_checked = 1
                post = {
                    "id": post_obj.id,
                    "title": post_obj.title,
                    "category_id": cate.id if cate else "",
                    "content": post_obj.body
                }
                self.render("management/update_post.html", post=post, category_list=category_list, tag_list=tag_list)
            else:
                self.write_error(404)
        except Exception as e:
            self.logger.error(e)
            self.write_error(404)

    @authenticated
    def post(self):
        result = self.result()
        try:
            data = self.get_body()
            post_id = data.get("post_id")
            title = self.data_null(data, "title", "请输入标题！")
            category_id = self.data_null(data, "category_id", "请选择分类！")
            tag_ids = self.data_null(data, "tags", "请选择标签！")
            content = self.data_null(data, "content", "请输入文章内容！")
            title_exist = self.session.query(Post)\
                              .filter(Post.id != post_id)\
                              .filter_by(title=title, author_id=self.current_user, is_delete=0)\
                              .first()
            if title_exist:
                self.data_except("当前标题已存在！")
            update_content = ""     # 文章修改的内容
            post_obj = self.session.query(Post).filter_by(title=title, author_id=self.current_user, is_delete=0).first()
            if not post_obj:
                self.write_error(404)
            # 分类是否更改
            cate = get_post_category(self, post_obj.id)
            if cate.id != int(category_id):
                update_content += "分类更改，"
                category_obj = self.session.query(Category) \
                                    .filter_by(id=int(category_id), author_id=self.current_user, is_delete=0) \
                                    .first()
                if category_obj:
                    post_cate_middle = self.session.query(PostCateMiddle).filter_by(post_id=post_obj.id).first()
                    post_cate_middle.category_id = category_obj.id
                else:
                    self.data_except("请确认文章分类是否正确！")
            # 标签是否更改
            tags = get_post_tags(self, post_obj.id)
            if sorted([int(i) for i in tag_ids]) != sorted([tag.id for tag in tags]):
                update_content += "标签更改，"
                # 删除关系
                self.session.query(PostTagMiddle).filter_by(post_id=post_obj.id).delete()
                # 重新确认关系
                new_post_tags = []
                for i in tag_ids:
                    tag_obj = self.session.query(Tag).filter_by(id=int(i), author_id=self.current_user, is_delete=0).first()
                    if tag_obj:
                        new_post_tags.append(PostTagMiddle(post_id=post_obj.id, tag_id=tag_obj.id))
                self.session.add_all(new_post_tags)

            if post_obj.title != title:
                post_obj.title = title
                update_content += "标题更改，"
            if post_obj.body != content:
                post_obj.excerpt = content[:100]
                post_obj.body = content
                update_content += "内容更改，"
            post_obj.modified_time = DateHandler.now()
            new_post_update = PostUpdateHistory(post_id=post_obj.id, change_content=update_content)
            self.session.add(new_post_update)
            self.session.commit()
            result["status"] = 1
            result["msg"] = "博文更改成功！"
        except Exception as e:
            self.session.rollback()
            self.logger.error(e)
            result = self.check_except_zh(e, msg="博文更改失败！")
        self.write(result)


class NewPostHandler(BaseHandler):
    @authenticated
    def get(self):
        category_obj = self.session.query(Category).filter_by(author_id=self.current_user, is_delete=0).order_by(Category.create_time.desc()).all()
        tag_obj = self.session.query(Tag).filter_by(author_id=self.current_user, is_delete=0).order_by(Tag.create_time.desc()).all()
        self.render("management/new_post.html", category_list=category_obj, tag_list=tag_obj)

    @authenticated
    def post(self):
        result = self.result()
        try:
            data = self.get_body()
            title = self.data_null(data, "title", "请输入标题！")
            category_id = self.data_null(data, "category_id", "请选择分类！")
            tags = self.data_null(data, "tags", "请选择标签！")
            content = self.data_null(data, "content", "请输入文章内容！")
            title_exist = self.session.query(Post).filter_by(title=title, author_id=self.current_user, is_delete=0).first()
            if title_exist:
                self.data_except("当前标题已存在！")
            # 新增文章
            new_post = Post(title=title, body=content, excerpt=content[:100], author_id=self.current_user)
            self.session.add(new_post)
            # 添加文章-分类关系
            category_obj = self.session.query(Category).filter_by(id=int(category_id), author_id=self.current_user, is_delete=0).first()
            if category_obj:
                new_post_cate = PostCateMiddle(post_id=new_post.id, category_id=category_obj.id)
                self.session.add(new_post_cate)
            else:
                self.data_except("请确认文章分类是否存在！")
            # 添加文章-标签关系
            new_post_tags = []
            for i in tags:
                tag_obj = self.session.query(Tag).filter_by(id=int(i), author_id=self.current_user, is_delete=0).first()
                if tag_obj:
                    new_post_tags.append(PostTagMiddle(post_id=new_post.id, tag_id=tag_obj.id))
            self.session.add_all(new_post_tags)
            self.session.commit()
            result["status"] = 1
            result["msg"] = "文章发表成功！"
            result["data"] = {
                "href": "/manage/post"
            }
        except Exception as e:
            self.session.rollback()
            self.logger.error(e)
            result = self.check_except_zh(e, msg="文章发表失败！")
        self.write(result)


class UpdatePostHandler(BaseHandler):
    @authenticated
    def get(self):
        if "api" in self.request.uri:
            result = self.result()
            try:
                data = self.get_params()
                page = int(data.get("page", 1))
                limit = int(data.get("limit", 10))
                posts = self.session.query(Post).filter_by(author_id=self.current_user, is_delete=0)
                post_count = posts.count()
                posts = posts.order_by(Post.create_time.desc()).limit(limit).offset((page - 1) * limit).all()
                data = []
                for post in posts:
                    # print(post.category[0].name)
                    # print([tag.name for tag in post.tags])
                    data.append({
                        "id": post.id,
                        "title": post.title,
                        "excerpt": post.excerpt,
                        "category": post.category[0].name,
                        "tags": [tag.name for tag in post.tags],
                        "views": post.views,
                        "comments": 0,
                        "modified_time": str(post.modified_time) if post.modified_time else "",
                        "create_time": str(post.create_time),
                    })
                result["status"] = 1
                result["msg"] = "查询成功！"
                result["data"] = {
                    "data_count": post_count,
                    "data_list": data
                }
            except Exception as e:
                self.logger.error(e)
                result = self.check_except_zh(e, msg="数据查询失败！")
            self.write(result)
        else:
            self.render("management/post.html")


